﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using AvalonDock;
using Genetic.Data;
using Genetic.Data.IO;
using Genetic.Properties;
using Microsoft.Win32;

namespace Genetic
{
    public partial class frmMain : Window
    {
        readonly frmProperties _propertiesForm = new frmProperties();
        frm3DViewer _systemEditor;

        public frmMain()
        {
            InitializeComponent();

            AddCommandBindings();

            //load layout
            dockingManager.Show(_propertiesForm, DockableContentState.Docked, AnchorStyle.Right);

            GetSettings();

            _propertiesForm.OptionsChanged += Properties_OptionsChanged;
            _propertiesForm.ContentChanged += Content_DisplayChanged;
        }

        void AddCommandBindings()
        {
            CommandBindings.Add(new CommandBinding(CustomCommands.NewMod, mnuNewMod_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.NewFile, mnuNewFile_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.OpenMod, mnuOpenMod_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.OpenFile, mnuOpenFile_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.OpenRecentFileShortCut, mnuOpenRecentFileShortCut_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.OpenRecentFile, mnuOpenRecentFile_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.Close, mnuClose_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.CloseMod, mnuCloseMod_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.Save, mnuSave_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.SaveAs, mnuSaveAs_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.SaveAll, mnuSaveAll_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.Exit, mnuExit_Click));

            CommandBindings.Add(new CommandBinding(CustomCommands.Undo, mnuNewFile_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.Redo, mnuNewFile_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.Cut, mnuNewFile_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.Copy, mnuNewFile_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.Paste, mnuNewFile_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.AddMenu, OpenAddMenu));
            CommandBindings.Add(new CommandBinding(CustomCommands.Add, mnuAddItem_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.Delete, mnuDelete_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.ChangeVisibility, mnuChangeVisibility_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.SelectAll, mnuSelectAll_Click));

            CommandBindings.Add(new CommandBinding(CustomCommands.PropertiesWindow, mnuProperties_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.SystemEditorWindow, mnu3DViewer_Click));

            CommandBindings.Add(new CommandBinding(CustomCommands.CloseAllDocuments, mnuCloseAllDocuments_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.Settings, mnuOptions_Click));

            CommandBindings.Add(new CommandBinding(CustomCommands.ReportIssue, mnuReportIssue_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.VisitForum, mnuVisitForum_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.CheckUpdate, mnuCheckUpdate_Click));
            CommandBindings.Add(new CommandBinding(CustomCommands.About, mnuAbout_Click));
        }

        void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (Helper.Settings.Data.Data.Forms.Main.Maximized)
            {
                WindowState = WindowState.Maximized;
            }

            //open files
            string[] arguments = Environment.GetCommandLineArgs();
            for (int i = 1; i < arguments.Length; ++i)
            {
                if (File.Exists(arguments[i]))
                {
                    OpenFile(arguments[i]);
                }
            }

            if (dockingManager.Documents.Length == 0)
            {
                SetDocumentMenus(false);
            }
        }

        void InitSystemEditor()
        {
            _systemEditor = new frm3DViewer();
            _systemEditor.SelectionChanged += systemEditor_SelectionChanged;
            _systemEditor.FileOpen += systemEditor_FileOpen;
            _systemEditor.DataManipulated += systemEditor_DataManipulated;
        }

        bool CloseAllDocuments()
        {
            foreach (DocumentContent child in dockingManager.Documents)
            {
                child.Close();
            }

            return true;
        }

        bool CloseOtherDocuments()
        {
            int index = 0;
            while (index < dockingManager.Documents.Length)
            {
                DocumentContent document = dockingManager.Documents[index];

                if (document != dockingManager.ActiveDocument)
                {
                    if (!document.Close())
                    {
                        return false;
                    }
                }
                else
                {
                    ++index;
                }
            }

            return true;
        }

        void DefaultEditor_DataChanged(ChangedData data)
        {
            if (_systemEditor != null)
            {
                if (data.Type == ChangedType.Add)
                {
                    _systemEditor.Add(data.NewBlocks);
                }
                else if (data.Type == ChangedType.Delete)
                {
                    _systemEditor.Delete(data.NewBlocks);
                }
                else if (data.Type == ChangedType.Edit)
                {
                    _systemEditor.SetValues(data.NewBlocks);
                }
            }
        }

        void DefaultEditor_SelectionChanged(ObservableCollection<TableBlock> data, int templateIndex)
        {
            if (data != null)
            {
                _propertiesForm.ShowData(data, templateIndex);

                if (_systemEditor != null)
                {
                    _systemEditor.Select(data[0]);
                }
            }
            else
            {
                _propertiesForm.ClearData();

                if (_systemEditor != null)
                {
                    _systemEditor.Deselect();
                }
            }
        }

        void DefaultEditor_DataVisibilityChanged(TableBlock block)
        {
            if (_systemEditor != null)
            {
                _systemEditor.SetVisibility(block);
            }
        }

        void Properties_OptionsChanged(PropertyBlock[] blocks)
        {
            frmTableEditor tableEditor = dockingManager.ActiveDocument as frmTableEditor;
            if (tableEditor != null)
            {
                tableEditor.SetBlocks(blocks);
            }
        }

        void mnuAbout_Click(object sender, RoutedEventArgs e)
        {
            //frmAbout frmAbout = new frmAbout();
            //frmAbout.ShowDialog();
        }

        void mnuVisitForum_Click(object sender, RoutedEventArgs e)
        {
            Process.Start("http://the-starport.net/freelancer/forum/viewtopic.php?topic_id=2174");
        }

        void mnuReportIssue_Click(object sender, RoutedEventArgs e)
        {
            Process.Start("http://code.google.com/p/freelancermodstudio/issues");
        }

        void mnuCloseAllDocuments_Click(object sender, RoutedEventArgs e)
        {
            CloseAllDocuments();
        }

        void SetSettings()
        {
            Helper.Settings.Data.Data.Forms.Main.Maximized = (WindowState == WindowState.Maximized);

            if (Helper.Settings.Data.Data.Forms.Main.Maximized)
            {
                WindowState = WindowState.Normal;
            }

            Helper.Settings.Data.Data.Forms.Main.Location = new Vector(Left, Top);
            Helper.Settings.Data.Data.Forms.Main.Size = new Vector(Width, Height);
        }

        void GetSettings()
        {
            if (Helper.Settings.Data.Data.Forms.Main.Size != new Vector(0, 0))
            {
                Left = Helper.Settings.Data.Data.Forms.Main.Location.X;
                Top = Helper.Settings.Data.Data.Forms.Main.Location.Y;

                Width = Helper.Settings.Data.Data.Forms.Main.Size.X;
                Height = Helper.Settings.Data.Data.Forms.Main.Size.Y;
            }

            DisplayRecentFiles();
        }

        void RemoveFromRecentFiles(string file)
        {
            for (int i = 0; i < Helper.Settings.Data.Data.Forms.Main.RecentFiles.Count; ++i)
            {
                if (Helper.Settings.Data.Data.Forms.Main.RecentFiles[i].File == file)
                {
                    Helper.Settings.Data.Data.Forms.Main.RecentFiles.RemoveAt(i);
                    break;
                }
            }
            DisplayRecentFiles();
        }

        void AddToRecentFiles(string file, int templateIndex)
        {
            //remove double files
            for (int i = 0; i < Helper.Settings.Data.Data.Forms.Main.RecentFiles.Count; ++i)
            {
                if (Helper.Settings.Data.Data.Forms.Main.RecentFiles[i].File.Equals(file, StringComparison.OrdinalIgnoreCase))
                {
                    Helper.Settings.Data.Data.Forms.Main.RecentFiles.RemoveAt(i);
                    i--;
                }
            }

            //insert new recentfile at first place
            Helper.Settings.Data.Data.Forms.Main.RecentFiles.Insert(0, new Settings.RecentFile
                {
                    File = file,
                    TemplateIndex = templateIndex
                });

            //remove last recentfile to keep ajusted amount of recentfiles
            if (Helper.Settings.Data.Data.Forms.Main.RecentFiles.Count > Helper.Settings.Data.Data.General.RecentFilesCount)
            {
                Helper.Settings.Data.Data.Forms.Main.RecentFiles.RemoveAt(Helper.Settings.Data.Data.Forms.Main.RecentFiles.Count - 1);
            }

            DisplayRecentFiles();
        }

        void DisplayRecentFiles()
        {
            int firstItemIndex = mnuOpen.Items.IndexOf(mnuOpenSeperator) + 1;

            //remove all recent menuitems
            for (int i = firstItemIndex; i < mnuOpen.Items.Count; i++)
            {
                mnuOpen.Items.RemoveAt(mnuOpen.Items.Count - 1);
                i--;
            }

            if (Helper.Settings.Data.Data.General.RecentFilesCount > 0 && Helper.Settings.Data.Data.Forms.Main.RecentFiles.Count > 0)
            {
                //add recent menuitems
                for (int i = 0; i < Helper.Settings.Data.Data.Forms.Main.RecentFiles.Count; i++)
                {
                    if (i < Helper.Settings.Data.Data.General.RecentFilesCount)
                    {
                        MenuItem menuItem = new MenuItem();
                        menuItem.Header = Path.GetFileName(Helper.Settings.Data.Data.Forms.Main.RecentFiles[i].File);
                        menuItem.CommandParameter = Helper.Settings.Data.Data.Forms.Main.RecentFiles[i];

                        if (i == 0)
                        {
                            menuItem.Command = CustomCommands.OpenRecentFileShortCut;
                        }
                        else
                        {
                            menuItem.Command = CustomCommands.OpenRecentFile;
                        }

                        mnuOpen.Items.Add(menuItem);
                    }
                }
                mnuOpenSeperator.Visibility = Visibility.Visible;
            }
            else
            {
                mnuOpenSeperator.Visibility = Visibility.Collapsed;
            }
        }

        void mnuOpenRecentFileShortCut_Click(object sender, RoutedEventArgs e)
        {
            if (Helper.Settings.Data.Data.Forms.Main.RecentFiles.Count > 0)
            {
                OpenRecentFile(Helper.Settings.Data.Data.Forms.Main.RecentFiles[0]);
            }
        }

        void mnuOpenRecentFile_Click(object sender, ExecutedRoutedEventArgs e)
        {
            OpenRecentFile(e.Parameter as Settings.RecentFile);
        }

        void OpenRecentFile(Settings.RecentFile recentFile)
        {
            try
            {
                OpenFile(recentFile.File, recentFile.TemplateIndex);
            }
            catch
            {
                if (MessageBox.Show(String.Format(Strings.FileErrorOpenRecent, recentFile.File), Helper.Assembly.Name, MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                {
                    RemoveFromRecentFiles(recentFile.File);
                }
            }
        }

        void OpenFile(string file)
        {
            int templateIndex = -1;
            int documentIndex = FileOpened(file);
            if (documentIndex == -1)
            {
                templateIndex = FileManager.GetTemplateIndex(file);
                if (templateIndex == -1)
                {
                    //let the user choose the ini file type
                    templateIndex = GetTemplateIndexDialog(file);
                }
            }

            try
            {
                OpenFile(file, templateIndex);
            }
            catch (Exception ex)
            {
                Helper.Exceptions.Show(String.Format(Strings.FileErrorOpen, file), ex);
            }
        }

        void OpenFile(string file, int templateIndex)
        {
            int documentIndex = FileOpened(file);
            if (documentIndex != -1)
            {
                dockingManager.ActiveDocument = dockingManager.Documents[documentIndex];
            }
            else
            {
                DisplayFile(file, templateIndex);
                AddToRecentFiles(file, templateIndex);
            }
        }

        void DisplayFile(string file, int templateIndex)
        {
            frmTableEditor editor = new frmTableEditor(templateIndex, file);
            editor.ShowData();

            editor.DataChanged += DefaultEditor_DataChanged;
            editor.SelectionChanged += DefaultEditor_SelectionChanged;
            editor.DataVisibilityChanged += DefaultEditor_DataVisibilityChanged;
            editor.ContentChanged += Content_DisplayChanged;
            editor.DocumentChanged += Document_DisplayChanged;

            dockDocuments.Items.Add(editor);
            dockingManager.ActiveDocument = editor;
        }

        void Window_Closing(object sender, CancelEventArgs e)
        {
            if (e.Cancel)
            {
                return;
            }

            /*if (CancelModClose())
            {
                e.Cancel = true;
                return;
            }*/

            SetSettings();
        }

        /*bool CancelModClose()
        {
            if (mod == null || mod.Data.About == null || mod.Data.About.Name == null || !modChanged)
            {
                return false;
            }

            DialogResult dialogResult = MessageBox.Show(String.Format(Strings.FileCloseSave, mod.Data.About.Name), Helper.Assembly.Name, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
            if (dialogResult == DialogResult.Cancel)
            {
                return true;
            }
            if (dialogResult == DialogResult.Yes)
            {
                //TODO: save current mod
            }

            return false;
        }

        void LoadMod(string file)
        {
            modChanged = false;
            //TODO:Load
        }*/

        //bool CancelFilesClose()
        //{
        //    foreach (DocumentContent content in dockingManager.Documents)
        //    {
        //        if (content is frmTableEditor)
        //        {
        //            dockingManager.ActiveDocument = content;
        //            if ((content as frmTableEditor).CancelClose())
        //            {
        //                return true;
        //            }
        //        }
        //    }

        //    return false;
        //}

        void mnuExit_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        void mnuCheckUpdate_Click(object sender, RoutedEventArgs e)
        {
            //Helper.Update.Check(false, false);
        }

        void AutoUpdate_RestartingApplication(object sender, CancelEventArgs e)
        {
            bool canceled = false;

            //close all MdiChildren and check if user canceled one
            foreach (DocumentContent child in dockingManager.Documents)
            {
                child.Close();
            }

            if (canceled)
            {
                e.Cancel = true;
            }
            else
            {
                Dispatcher.Invoke(new Action(delegate { Close(); }));
            }
        }

        void mnuNewMod_Click(object sender, RoutedEventArgs e)
        {
        }

        void mnuOpenMod_Click(object sender, RoutedEventArgs e)
        {
        }

        void mnuCloseMod_Click(object sender, RoutedEventArgs e)
        {
        }

        void dockingManager_ActiveDocumentChanged()
        {
            //show properties of document if active document changed
            frmTableEditor tableEditor = dockingManager.ActiveDocument as frmTableEditor;
            if (tableEditor != null)
            {
                if (_systemEditor != null && !tableEditor.CanDisplay3DViewer())
                {
                    //CloseSystemEditor();
                    _systemEditor.Clear(false, false);
                }
                else
                {
                    ShowSystemEditor(tableEditor);
                }

                // set selection changed after showing/closing the system editor as this needs to be forwarded to system editor
                DefaultEditor_SelectionChanged(tableEditor.GetSelectedBlocks(), tableEditor.Data.TemplateIndex);
                Document_DisplayChanged(tableEditor);
            }
            else
            {
                DefaultEditor_SelectionChanged(null, 0);

                if (_systemEditor != null)
                {
                    //CloseSystemEditor();
                    _systemEditor.Clear(false, false);
                }
            }
        }

        void ShowSystemEditor(frmTableEditor editor)
        {
            if (_systemEditor != null)
            {
                _systemEditor.ShowViewer(editor.ViewerType);

                // set data path before showing the models
                _systemEditor.DataPath = editor.DataPath;

                switch (editor.ViewerType)
                {
                    case ViewerType.System:
                        // set model mode as it was reset if the editor was closed
                        //_systemEditor.IsModelMode = mnuShowModels.Checked;
                        _systemEditor.ShowData(editor.Data);
                        break;
                    case ViewerType.Universe:
                        _systemEditor.IsModelMode = false;
                        _systemEditor.ShowData(editor.Data);
                        _systemEditor.ShowUniverseConnections(editor.File, editor.Data.Blocks, editor.Archetype);
                        break;
                    case ViewerType.SolarArchetype:
                    case ViewerType.ModelPreview:
                        _systemEditor.IsModelMode = true;
                        break;
                }

                //select initially
                ObservableCollection<TableBlock> blocks = editor.GetSelectedBlocks();
                if (blocks != null)
                {
                    _systemEditor.Select(blocks[0]);
                }
            }
        }

        void mnuOptions_Click(object sender, RoutedEventArgs e)
        {
            //frmOptions optionsForm = new frmOptions();
            //optionsForm.ShowDialog();

            //SettingsChanged();
        }

        void mnuOpenFile_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog fileOpener = new OpenFileDialog
                {
                    Filter = Strings.FileDialogFilter
                };
            if (fileOpener.ShowDialog().Value)
            {
                foreach (string file in fileOpener.FileNames)
                {
                    OpenFile(file);
                }
            }
        }

        void mnuSaveAll_Click(object sender, RoutedEventArgs e)
        {
            foreach (DocumentContent document in dockingManager.Documents)
            {
                frmTableEditor tableEditor = document as frmTableEditor;
                if (tableEditor != null)
                {
                    tableEditor.Save();
                }
            }
        }

        int FileOpened(string file)
        {
            int i = 0;
            foreach (DocumentContent document in dockingManager.Documents)
            {
                frmTableEditor tableEditor = document as frmTableEditor;
                if (tableEditor != null)
                {
                    if (tableEditor.File.Equals(file, StringComparison.OrdinalIgnoreCase))
                    {
                        return i;
                    }
                }
                ++i;
            }
            return -1;
        }

        void frmMain_DragEnter(object sender, DragEventArgs e)
        {
            e.Effects = e.Data.GetDataPresent(DataFormats.FileDrop) ? DragDropEffects.Copy : DragDropEffects.None;
        }

        void frmMain_DragDrop(object sender, DragEventArgs e)
        {
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
            foreach (string file in files)
            {
                OpenFile(file);
            }
        }

        void mnuProperties_Click(object sender, RoutedEventArgs e)
        {
            dockingManager.Show(_propertiesForm, DockableContentState.Docked, AnchorStyle.Right);
        }

        void mnuNewFile_Click(object sender, RoutedEventArgs e)
        {
            //let the user choose the ini file type
            int templateIndex = GetTemplateIndexDialog(null);
            if (templateIndex != -1)
            {
                DisplayFile(null, templateIndex);
            }
        }

        void mnuSave_Click(object sender, RoutedEventArgs e)
        {
            IDocumentForm document = dockingManager.ActiveDocument as IDocumentForm;
            if (document != null)
            {
                try
                {
                    document.Save();
                }
                catch (Exception ex)
                {
                    Helper.Exceptions.Show(String.Format(Strings.FileErrorSave, document.GetTitle()), ex);
                }
            }
        }

        void mnuSaveAs_Click(object sender, RoutedEventArgs e)
        {
            frmTableEditor tableEditor = dockingManager.ActiveDocument as frmTableEditor;
            if (tableEditor != null)
            {
                try
                {
                    tableEditor.SaveAs();

                    AddToRecentFiles(tableEditor.File, tableEditor.Data.TemplateIndex);
                }
                catch (Exception ex)
                {
                    Helper.Exceptions.Show(String.Format(Strings.FileErrorSave, tableEditor.GetTitle()), ex);
                }
            }
        }

        IContentForm GetContent()
        {
            IContentForm content = dockingManager.ActiveContent as IContentForm;
            if (content != null && content.UseDocument())
            {
                content = dockingManager.ActiveDocument as IContentForm;
                if (content != null)
                {
                    return content;
                }

                return null;
            }

            return content;
        }

        IDocumentForm GetDocument()
        {
            return dockingManager.ActiveDocument as IDocumentForm;
        }

        void mnuCut_Click(object sender, RoutedEventArgs e)
        {
            IContentForm content = GetContent();
            if (content != null)
            {
                content.Cut();
            }
        }

        void mnuCopy_Click(object sender, RoutedEventArgs e)
        {
            IContentForm content = GetContent();
            if (content != null)
            {
                content.Copy();
            }
        }

        void mnuPaste_Click(object sender, RoutedEventArgs e)
        {
            IContentForm content = GetContent();
            if (content != null)
            {
                content.Paste();
            }
        }

        void mnuUndo_Click(object sender, RoutedEventArgs e)
        {
            IDocumentForm content = GetDocument();
            if (content != null)
            {
                content.Undo();
            }
        }

        void mnuRedo_Click(object sender, RoutedEventArgs e)
        {
            IDocumentForm content = GetDocument();
            if (content != null)
            {
                content.Redo();
            }
        }

        void mnuClose_Click(object sender, RoutedEventArgs e)
        {
            if (dockingManager.ActiveDocument != null && dockingManager.ActiveDocument is frmTableEditor)
            {
                (dockingManager.ActiveDocument as frmTableEditor).Close();
            }
        }

        void OpenAddMenu(object sender, RoutedEventArgs e)
        {
            mnuEdit.IsSubmenuOpen = true;
            mnuAdd.IsSubmenuOpen = true;
        }

        void mnuAddItem_Click(object sender, ExecutedRoutedEventArgs e)
        {
            IContentForm content = GetContent();
            if (content != null)
            {
                AddInfo info = e.Parameter as AddInfo;
                if (info != null)
                {
                    content.Add(info.Index);
                }
            }
        }

        void mnuDelete_Click(object sender, RoutedEventArgs e)
        {
            IContentForm content = GetContent();
            if (content != null)
            {
                content.Delete();
            }
        }

        void mnuSelectAll_Click(object sender, RoutedEventArgs e)
        {
            IContentForm content = GetContent();
            if (content != null)
            {
                content.SelectAll();
            }
        }

        void mnuChangeVisibility_Click(object sender, RoutedEventArgs e)
        {
            IDocumentForm content = GetDocument();
            if (content != null)
            {
                content.ChangeVisibility();
            }
        }

        //void dockPanel1_ContentAdded(object sender, DockContentEventArgs e)
        //{
        //    if (e.Content is frmTableEditor)
        //        SetDocumentMenus(true);
        //}

        //void dockPanel1_ContentRemoved(object sender, DockContentEventArgs e)
        //{
        //    if (e.Content is frmSystemEditor)
        //    {
        //        //dispose system editor
        //        systemEditor.Dispose();
        //        systemEditor = null;
        //    }
        //    else if (e.Content is frmTableEditor)
        //    {
        //        foreach (IDockContent document in dockPanel1.Documents)
        //        {
        //            //there is at least one editor left in documents pane
        //            if (document is frmTableEditor)
        //                return;
        //        }

        //        //no editors found
        //        SetDocumentMenus(false);

        //        if (systemEditor != null)
        //            systemEditor.Clear();
        //    }
        //}

        void SetDocumentMenus(bool value)
        {
            if (!value)
            {
                //mnuSave.Header = string.Format(Strings.FileEditorSave, Strings.SelectedItems);
                //mnuSaveAs.Header = string.Format(Strings.FileEditorSaveAs, Strings.SelectedItems);
            }

            mnuSave.IsEnabled = value;
            mnuSaveAs.IsEnabled = value;
            mnuSaveAll.IsEnabled = value;
            mnuClose.IsEnabled = value;
            mnuCloseAllDocuments.IsEnabled = value;
        }

        void Document_DisplayChanged(IDocumentForm document)
        {
            if (document == null)
            {
                SetDocumentMenus(false);
                mnuUndo.IsEnabled = false;
                mnuRedo.IsEnabled = false;
                mnuChangeVisibility.Visibility = Visibility.Collapsed;
                Title = Helper.Assembly.Name;
                return;
            }

            Title = document.GetTitle();

            if (document.CanSave())
            {
                mnuSave.Header = String.Format(Strings.FileEditorSave, Title);
                mnuSaveAs.Header = String.Format(Strings.FileEditorSaveAs, Title);
            }

            mnuUndo.IsEnabled = document.CanUndo();
            mnuRedo.IsEnabled = document.CanRedo();

            if (document.CanChangeVisibility(false))
            {
                mnuChangeVisibility.Visibility = Visibility.Visible;
            }
            else
            {
                mnuChangeVisibility.Visibility = Visibility.Collapsed;
            }

            SetDocumentMenus(true);
        }

        void Content_DisplayChanged(IContentForm content)
        {
            mnuAdd.Items.Clear();

            if (content == null)
            {
                mnuCopy.IsEnabled = false;
                mnuCut.IsEnabled = false;
                mnuPaste.IsEnabled = false;
                mnuAdd.IsEnabled = false;
                mnuDelete.IsEnabled = false;
                mnuSelectAll.IsEnabled = false;

                mnuChangeVisibility.IsEnabled = false;
            }
            else
            {
                mnuCopy.IsEnabled = content.CanCopy();
                mnuCut.IsEnabled = content.CanCut();
                mnuPaste.IsEnabled = content.CanPaste();
                mnuAdd.IsEnabled = content.CanAdd();
                mnuDelete.IsEnabled = content.CanDelete();
                mnuSelectAll.IsEnabled = content.CanSelectAll();
                mnuChangeVisibility.IsEnabled = true;

                //if (content.CanAddMultiple())
                AddInfo[] multiInfo = content.MultipleAddDropDown();
                if (multiInfo != null)
                {
                    foreach (AddInfo info in multiInfo)
                    {
                        MenuItem item = new MenuItem();
                        item.Header = info.Text;
                        item.CommandParameter = info;
                        item.Command = CustomCommands.Add;

                        mnuAdd.Items.Add(item);
                    }
                }
            }
        }

        void dockingManager_ActiveContentChanged()
        {
            Content_DisplayChanged(GetContent());
        }

        void mnu3DViewer_Click(object sender, RoutedEventArgs e)
        {
            if (_systemEditor == null)
            {
                InitSystemEditor();

                dockingManager.Show(_systemEditor, DockableContentState.Docked, AnchorStyle.Left);
            }
            else
            {
                dockingManager.Show(_systemEditor);
            }

            frmTableEditor tableEditor = dockingManager.ActiveDocument as frmTableEditor;
            if (tableEditor != null)
            {
                ShowSystemEditor(tableEditor);
            }
        }

        void systemEditor_FileOpen(string path)
        {
            frmTableEditor tableEditor = dockingManager.ActiveDocument as frmTableEditor;
            if (tableEditor != null)
            {
                string file = string.Empty;

                try
                {
                    string directory = Path.GetDirectoryName(tableEditor.File);
                    if (directory != null)
                    {
                        file = Path.Combine(directory, path);
                        if (File.Exists(file))
                        {
                            OpenFile(file, Helper.Template.Data.SystemFile);
                        }
                        else
                        {
                            throw new FileNotFoundException();
                        }
                    }
                }
                catch (Exception ex)
                {
                    Helper.Exceptions.Show(String.Format(Strings.FileErrorOpen, file), ex);
                }
            }
        }

        void systemEditor_SelectionChanged(TableBlock block, bool toggle)
        {
            frmTableEditor tableEditor = dockingManager.ActiveDocument as frmTableEditor;
            if (tableEditor != null)
            {
                tableEditor.Select(block, toggle);
            }
        }

        void systemEditor_DataManipulated(TableBlock newBlock, TableBlock oldBlock)
        {
            frmTableEditor tableEditor = dockingManager.ActiveDocument as frmTableEditor;
            if (tableEditor != null)
            {
                tableEditor.SetBlocks(new ObservableCollection<TableBlock> { newBlock }, new ObservableCollection<TableBlock> { oldBlock });
            }
        }

        void dockingManager_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "ActiveContent")
            {
                dockingManager_ActiveContentChanged();
            }
            else if (e.PropertyName == "ActiveDocument")
            {
                dockingManager_ActiveDocumentChanged();
            }
        }

        void Maximize()
        {
            if (WindowState == WindowState.Normal)
            {
                WindowState = WindowState.Maximized;
            }
            else
            {
                WindowState = WindowState.Normal;
            }
        }

        void Window_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount == 2)
            {
                Maximize();
            }
            else
            {
                DragMove();
            }
        }

        int GetTemplateIndexDialog(string file)
        {
            //let the user choose the ini file type
            frmFileType fileTypeForm = new frmFileType(file)
                {
                    Owner = this
                };
            if (fileTypeForm.ShowDialog().Value && fileTypeForm.FileTypeIndex >= 0)
            {
                return fileTypeForm.FileTypeIndex;
            }

            return -1;
        }
    }
}
